home *** CD-ROM | disk | FTP | other *** search
/ Netscape Plug-Ins Developer's Kit / Netscape_Plug-Ins_Developers_Kit.iso / CGIPERL / MACPERL / MSRCE418.HQX / Perl Source ƒ / MacPerl / MPPseudoFile.cp < prev    next >
Encoding:
Text File  |  1994-09-19  |  3.6 KB  |  184 lines

  1. /*********************************************************************
  2. Project    :    MacPerl                -    Standalone Perl
  3. File        :    MPPseudoFile.cp    -    Pseudo files for GUSI
  4. Author    :    Matthias Neeracher
  5. Language    :    MPW C/C++
  6. $Log: MPPseudoFile.cp,v $
  7. Revision 1.1  1994/02/27  23:05:08  neeri
  8. Initial revision
  9.  
  10. *********************************************************************/
  11.  
  12. #include <GUSIFile_P.h>
  13.  
  14. #include <ioctl.h>
  15. #include <sys/types.h>
  16. #include <Resources.h>
  17. #include <TextUtils.h>
  18.  
  19. extern "C" {
  20. #include "MPGlobals.h"
  21. }
  22.  
  23. #define AF_PSEUDO 18
  24.  
  25. class MPPseudoSocket;                             // That's what this file's all about
  26.  
  27. class MPPseudoSocket : public Socket    {        
  28.     friend class MPPseudoSocketDomain;    
  29.     
  30.                     MPPseudoSocket(Handle hdl);
  31.                     
  32.     virtual         ~MPPseudoSocket();
  33.     
  34.     Handle        data;
  35.     long            readEnd;
  36.     long            readPtr;
  37. public:
  38.     virtual int    read(void * buffer, int buflen);
  39.     virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
  40.     virtual int    ioctl(unsigned int request, void *argp);
  41.     virtual long lseek(long offset, int whence);
  42. };    
  43.  
  44. class MPPseudoSocketDomain : public FileSocketDomain {
  45. public:
  46.     MPPseudoSocketDomain()    :    FileSocketDomain(AF_PSEUDO, true, false)    {    }
  47.     
  48.     virtual Boolean Yours(const GUSIFileRef & ref, Request request);
  49.     virtual Socket * open(const GUSIFileRef & ref, int oflag);
  50. };
  51.  
  52. MPPseudoSocketDomain    MPPseudoSockets;
  53.  
  54. #if !defined(powerc) && !defined(__powerc)
  55. #pragma segment MPPseudo
  56. #endif
  57.  
  58. /************************ MPPseudoSocket members ************************/
  59.  
  60. MPPseudoSocket::MPPseudoSocket(Handle hdl)
  61.     : data(hdl)
  62. {
  63.     readPtr    =    0;
  64.     readEnd    =    GetHandleSize(data);
  65. }
  66.  
  67. MPPseudoSocket::~MPPseudoSocket()
  68. {
  69.     DisposeHandle(data);
  70. }
  71.  
  72. int MPPseudoSocket::ioctl(unsigned int request, void *argp)
  73. {
  74.     switch (request)    {
  75.     case FIONREAD:
  76.         *(unsigned long *) argp    = readEnd - readPtr;
  77.         
  78.         return 0;
  79.     default:
  80.         return GUSI_error(EOPNOTSUPP);
  81.     }
  82. }
  83.  
  84. int MPPseudoSocket::read(void * buffer, int buflen)
  85. {
  86.     buflen = min(int(readEnd - readPtr), buflen);
  87.     
  88.     memcpy(buffer, (*data) + readPtr, buflen);
  89.     
  90.     readPtr += buflen;
  91.     
  92.     return buflen;
  93. }
  94.  
  95. int MPPseudoSocket::select(Boolean * canRead, Boolean * canWrite, Boolean * exception)
  96. {
  97.     int        goodies     =     0;
  98.         
  99.     if (canRead)
  100.         if (*canRead = readEnd > readPtr)
  101.             ++goodies;
  102.     
  103.     if (canWrite)
  104.         *canWrite = false;
  105.     
  106.     if (exception)
  107.         *exception = false;
  108.     
  109.     return goodies;
  110. }
  111.  
  112. long MPPseudoSocket::lseek(long offset, int whence)
  113. {
  114.     long    nuReadPtr;
  115.     
  116.     switch (whence) {
  117.     case SEEK_END:
  118.         nuReadPtr = readEnd + offset;
  119.         break;
  120.     case SEEK_CUR:
  121.         nuReadPtr = readPtr + offset;
  122.         break;
  123.     case SEEK_SET:
  124.         nuReadPtr = offset;
  125.         break;
  126.     default:
  127.         return GUSI_error(EINVAL);
  128.     }
  129.     
  130.     if (nuReadPtr > readEnd)
  131.         return GUSI_error(ESPIPE);
  132.     if (nuReadPtr < 0)
  133.         return GUSI_error(EINVAL);
  134.     
  135.     return readPtr = nuReadPtr;
  136. }
  137.  
  138. /********************* MPPseudoSocketDomain member **********************/
  139.  
  140. #if !defined(powerc) && !defined(__powerc)
  141. #pragma force_active on
  142. #endif
  143.  
  144. Boolean MPPseudoSocketDomain::Yours(const GUSIFileRef & ref, FileSocketDomain::Request)
  145. {
  146.     char      name[8];
  147.  
  148.     strncpy(name, ref.name+4, 6);
  149.     name[6] = 0;
  150.     
  151.     return equalstring(name, (char *) "pseudo", false, true);
  152. }
  153.  
  154. Socket * MPPseudoSocketDomain::open(const GUSIFileRef & ref, int flags)
  155. {
  156.     Socket *            sock = nil;
  157.  
  158.     if (flags & ~O_BINARY)
  159.         return (Socket *) GUSI_error_nil(EPERM);
  160.         
  161.     if (!ref.name[10]) {
  162.         sock = new MPPseudoSocket(gPseudoFile);
  163.         
  164.         gPseudoFile = nil;
  165.     } else {
  166.         short        res    =    CurResFile();
  167.         Handle    data;
  168.         
  169.         UseResFile(gScriptFile);
  170.         
  171.         data = getnamedresource('TEXT', (char *) ref.name+11);
  172.         
  173.         if (data) {
  174.             DetachResource(data);
  175.             
  176.             sock = new MPPseudoSocket(data); 
  177.         }
  178.         
  179.         UseResFile(res);
  180.     }
  181.  
  182.     return sock;
  183. }
  184.